﻿desc:OFS
//options:no_meter
/* Есть впорос по beat-position. В темпах, где denom != 4.
Рипер отдает согласно размеру, например, 4/8 - beat равен 1/8.
Но VST, в основном, считают beat четвертью(QN).
И хер поймешь кто здесь прав. */

..import inc\FuncForJeez.jsfx-inc
import inc\mouse3Full.jsfx-inc
import inc\Curve OFS v1-1.jsfx-inc
import inc\Grid1-2.jsfx-inc

filename:0,OffMed1-1.png


slider1:0<0,1,1{Retrig(Aux L+R),BeatSync}>Mode
slider2:1<0,6,1{1/16,1/8,1/4,1/2,3/4,4/4,8/4,16/4}>Length(you can add any value)
slider3:-10<-30,0,0.1>Treshold(for Retrig mode)
slider4:0<0,9,1>Curve

in_pin:main L
in_pin:main R
in_pin:aux L
in_pin:aux R
out_pin:main L
out_pin:main R
out_pin:aux L
out_pin:aux R

@init
ext_noinit = 1;
//------------
R = G = B = 30;  // color for test 
gfx_clear = R+G*256+B*65536;

/*--------------------------------------------------------------
---- Create Curve ----------------------------------------------
--------------------------------------------------------------*/
offs = 0; 
crv_A.Curve_Init(40,20,720,240, offs, 128, 10); // init curve!
/*--------------------------------------------------------------
---- Create Controls -------------------------------------------
--------------------------------------------------------------*/
//args = //

@slider

function GetLoopLenQN()
  local(str,nm,dnm)
( 
  nm = dnm = 0;
  strcpy_fromslider(str, slider2);
  match("%d/%d", str , nm, dnm );
  nm/dnm * 4;
);

Mode = slider1;
looplenQN  = GetLoopLenQN(); // len from slider2
tresh = 10^(slider3/20);

crv_A.Curve_SetActiveBuf(slider4); // Это главное!

@serialize
crv_A.Curve_Serialize()  // Хуярим весь кусок памяти, включая мелочи
  
@block
/* Позиция(beat_pos) автом. обновляется при проигрывании, позволяет учитывать изм. темпа.
В остановл. состоянии используются данные в поз. курсора */

play_state ? beat_pos = beat_position; // beat position on block start(upd when playing only)
beats_per_spl = tempo/(60 * srate);

@sample

beat_pos += beats_per_spl; // spl_acc beat position

Mode==0 ? (
  abs(spl2+spl3)*0.5 > tresh && !Trig ? (
    trig_pos = beat_pos; 
    Trig=1;
  );
  
  Trig ? (
    Xpos = (beat_pos - trig_pos)/looplenQN;
    Xpos >=1 || Xpos < 0 ? Trig = 0;
    gain = crv_A.Curve_App_to_Val(Xpos);
    spl0 *= gain;
    spl1 *= gain;
  );
) : (
  Mode==1 ? (
    Xpos = beat_pos/looplenQN;
    Xpos = Xpos - floor(Xpos); // Rel pos(0...1 НЕ дробная часть, а именно отн. позиция)!
    gain = crv_A.Curve_App_to_Val(Xpos);
    spl0 *= gain;
    spl1 *= gain;
  );
);


@gfx 800 400
// Это шутка, но без нее я не мог!
function PngOFS(x,y,w,h)
  local(aT)
(
  //-- Set knob image ------------------------------------------
  
  img = 0;
  gfx_getimgdim(img, pw, ph);
  gfx_x=gfx_y=0;
  gfx_a = a;
  gfx_blit(img,1,0, 0,0,pw,ph, 0,0,gfx_w,gfx_h );
  aT ? a<0.025 ? a+=0.0001 : aT=0;
  !aT ? a>0.005 ? a-=0.0001 : aT=1;
);

//--------------------
function Grid(x,y,w,h)
(
  Draw_BG(x,y,w,h); // Background - (x,y,w,h)
  PngOFS(x,y,w,h);
  gfx_set(0.5,1,0.5, 0.15);  // grid lines color
  Draw_Grid(x,y,w,h, 17);   // args = (x,y,w,h, n_lines)
  gfx_setfont(1,"Calibri", 14); // values font
  gfx_set(0.6,0.6,0.6,0.8); // values color
  Draw_GridValues(x,y,w,h, "dB");
);

//-- Draw Controls ---------------------
function Draw_Controls()
  local(x,y,w,h)
(
  x = 40; y = 20; w = gfx_w-60; h = gfx_h-60;
  Grid(x,y,w,h);
  gfx_set(0.5,1,0.5, 0.7);  // Curve color
  crv_A.Curve_SetCoord(x,y,w,h);
  crv_A.Curve_Draw();
  crv_A.Curve_SetActiveBuf(slider4); // Это главное!
 
);



//--------------------------------------

GetMouseState(); 
Draw_Controls();
SetMouseLastState();















